#!/bin/bash

# 全局变量
new=0
hash=0
CURSOR_X=0
CURSOR_Y=0
CURSOR_VISIBLE=true
MOUSE_CLICK=false
VNC_PORT=5901
VNC_PASSWORD="password"
USE_VNC=false
declare -A previous_pixels  # 存储前一帧的像素数据

# 获取终端尺寸并计算虚拟桌面大小
get_terminal_size() {
    cols=$(tput cols)
    lines=$(tput lines)
    SCREEN_WIDTH=$cols
    SCREEN_HEIGHT=$((lines-1))  # 留一行给状态栏
    
    # 计算虚拟桌面大小（字符的8倍宽和16倍高）
    VIRTUAL_WIDTH=$((cols * 8))
    VIRTUAL_HEIGHT=$(( (lines-1) * 16 ))
    
    # 确保光标不会超出范围
    [ $CURSOR_X -ge $SCREEN_WIDTH ] && CURSOR_X=$((SCREEN_WIDTH-1))
    [ $CURSOR_Y -ge $SCREEN_HEIGHT ] && CURSOR_Y=$((SCREEN_HEIGHT-1))
    
    # 清空像素缓存
    previous_pixels=()
}

# 检查依赖
check_dependencies() {
    apt-get update
    sudo apt install -y scrot xvfb xdotool openssh-server xfce4 xfce4-terminal dbus-x11 imagemagick xfe novnc websockify bc
    apt-get clean
    find /tmp -delete
    mkdir /tmp
}

# 初始化虚拟显示（完全根据终端大小）
setup_xvfb() {
    get_terminal_size
    echo "初始化虚拟桌面: ${VIRTUAL_WIDTH}x${VIRTUAL_HEIGHT}"
    
    Xvfb :99 -screen 0 ${VIRTUAL_WIDTH}x${VIRTUAL_HEIGHT}x24 &
    export DISPLAY=:99
    startxfce4 >/dev/null 2>&1 &
    sleep 10
    
    # 设置桌面背景为拉伸模式
    xfconf-query -c xfce4-desktop -p /backdrop/screen0/monitor0/workspace0/image-style -s 5
}

# 设置VNC服务器
setup_vnc() {
    get_terminal_size
    sudo apt install -y tigervnc-standalone-server
    
    mkdir -p ~/.vnc
    echo "$VNC_PASSWORD" | vncpasswd -f > ~/.vnc/passwd
    chmod 600 ~/.vnc/passwd
    
    # 使用计算出的虚拟大小
    vncserver :99 -geometry ${VIRTUAL_WIDTH}x${VIRTUAL_HEIGHT} -depth 24 -SecurityTypes VncAuth -xstartup startxfce4
    
    websockify -D --web=/usr/share/novnc/ $VNC_PORT localhost:5999
    
    echo "VNC服务器已启动，分辨率: ${VIRTUAL_WIDTH}x${VIRTUAL_HEIGHT}"
    echo "访问方式:"
    echo "1. 直接VNC连接: localhost:$VNC_PORT"
    echo "2. Web访问: http://localhost:$VNC_PORT/vnc.html"
    echo "密码: $VNC_PASSWORD"
}

# 绘制光标
draw_cursor() {
        tput cup $CURSOR_Y $CURSOR_X
        echo -ne "\e[1;37;40mX\e[0m"  
}

# 鼠标点击函数（现在使用虚拟桌面比例计算）
simulate_click() {
    local button=$1
    local x=$((CURSOR_X * VIRTUAL_WIDTH / SCREEN_WIDTH))
    local y=$((CURSOR_Y * VIRTUAL_HEIGHT / SCREEN_HEIGHT))
    xdotool mousemove $x $y click $button
    MOUSE_CLICK=true
}

# 优化的图像显示函数 - 只更新变化的像素
draw_image() {
if command -v convert &> /dev/null; then
    scrot -o screenshot.png
        new=$(convert screenshot.png -scale ${SCREEN_WIDTH}x${SCREEN_HEIGHT}\! -format "%[fx:int(255*r)],%[fx:int(255*g)],%[fx:int(255*b)]" info:)
        if [ "$new" != "$hash" ]; then
            hash="$new"
            tput cup 1 1
        convert screenshot.png -resize ${SCREEN_WIDTH}x${SCREEN_HEIGHT}\! -depth 8 txt:- | \
        awk -v width="$SCREEN_WIDTH" -v height="$SCREEN_HEIGHT" '
            BEGIN { line=1; col=1 }
            NR>1 {
                gsub(/.*\(/, ""); gsub(/\).*/, ""); 
                split($0, rgb, ","); 
                printf "\033[%d;%dH\033[48;2;%d;%d;%dm ", line, col, rgb[1], rgb[2], rgb[3]
                if (col++ >= width) { col=1; line++ }
                if (line > height) exit
            }'
        fi
    else
        sudo apt install -y imagemagick
    fi
}

# 绘制状态栏
draw_status_bar() {
    tput cup $SCREEN_HEIGHT 0
    echo -ne "\e[44;37m"
    printf "方向键移动 | L:左键 R:右键 | Q:退出 | 位置: (%3d,%3d)" $CURSOR_X $CURSOR_Y
    $MOUSE_CLICK && echo -n " [点击]" || echo -n "      "
    printf '%*s' $(($SCREEN_WIDTH-$(tput cols))) ''
    echo -ne "\e[0m"
    MOUSE_CLICK=false
}

# 主绘制循环
draw_screen() {
    draw_image
    draw_status_bar
    draw_cursor
    sleep 0.1
}

# 输入处理
handle_input() {
    local blink_counter=0
    while true; do
        read -rsn1 -t 0.1 key
        
        case "$key" in
            $'\x1b')  # ESC序列
                read -rsn2 -t 0.1 seq
                case "$seq" in
                    '[A') CURSOR_Y=$((CURSOR_Y-1)); [ $CURSOR_Y -lt 0 ] && CURSOR_Y=0 ;;
                    '[B') CURSOR_Y=$((CURSOR_Y+1)) ;;
                    '[C') CURSOR_X=$((CURSOR_X+1)) ;;
                    '[D') CURSOR_X=$((CURSOR_X-1)); [ $CURSOR_X -lt 0 ] && CURSOR_X=0 ;;
                esac
                # 清空光标周围的像素缓存，确保光标移动后能正确重绘
                for ((dx=-1; dx<=1; dx++)); do
                    for ((dy=-1; dy<=1; dy++)); do
                        nx=$((CURSOR_X+dx))
                        ny=$((CURSOR_Y+dy))
                        [ $nx -ge 0 ] && [ $nx -lt $SCREEN_WIDTH ] && [ $ny -ge 0 ] && [ $ny -lt $SCREEN_HEIGHT ] && \
                        unset previous_pixels["$nx,$ny"]
                    done
                done
                ;;
            'l'|'L') simulate_click 1 ;;
            'r'|'R') simulate_click 3 ;;
            'q'|'Q') 
                pkill Xvfb
                pkill startxfce4
                [ "$USE_VNC" = true ] && vncserver -kill :99
                exit 0
                ;;
        esac
        
        # 边界检查
        get_terminal_size
        
        # 光标闪烁控制
        blink_counter=$(( (blink_counter+1) %5 ))
        CURSOR_VISIBLE=$(( blink_counter <4 ))
        
        draw_screen
    done
}

# 显示菜单
show_menu() {
    clear
    echo "=============================================="
    echo "        桌面控制工具 (终端大小: $(tput cols)x$(tput lines))"
    echo "=============================================="
    echo "1. 终端字符控制 (自适应大小)"
    echo "2. 使用VNC远程控制"
    echo "3. 设置VNC密码 (当前: $VNC_PASSWORD)"
    echo "4. 退出"
    echo "=============================================="
    read -p "请选择 [1-4]: " choice

    case $choice in
        1) USE_VNC=false; setup_xvfb ;;
        2) USE_VNC=true; setup_vnc; read -p "按回车返回" ;;
        3) read -sp "新密码: " VNC_PASSWORD; echo; show_menu ;;
        4) exit 0 ;;
        *) echo "无效选择!"; sleep 1; show_menu ;;
    esac
}

# 主程序
main() {
    check_dependencies
    get_terminal_size
    show_menu
    
    if [ "$USE_VNC" = false ]; then
        handle_input
    else
        echo "VNC运行中... 按Ctrl+C停止"
        wait
    fi
}

# 捕获信号
trap 'get_terminal_size; previous_pixels=()' WINCH
trap 'pkill Xvfb; pkill startxfce4; [ "$USE_VNC" = true ] && vncserver -kill :99; exit 0' SIGINT

main